﻿using MovingChame.Web.Helpers;
using MovingChame.Web.Infrastructure;
using MovingChame.Web.Models;
using System;
using System.Collections.Generic;
using System.Data.Spatial;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Web.Security;

namespace MovingChame.Web.Services
{
    public class TourService : ITourService
    {
        #region Properties
        ITourProvider tourProvider;
        ILocationProvider locationProvider;
        IScheduleProvider scheduleProvider;
        #endregion

        #region Constructor
        public TourService()
        {
            tourProvider = TourProvider.Current;
            locationProvider = LocationProvider.Current;
            scheduleProvider = ScheduleProvider.Current;
        }
        #endregion

        #region Search Tours
        public List<TourData> SearchTour(string keyword)
        {
            List<TourData> result = new List<TourData>();

            if (string.IsNullOrEmpty(keyword))
                return result;

            List<Location> locations = locationProvider.SearchLocation(keyword).ToList();
            IQueryable<Tour> searchInTour = tourProvider.SearchTours(keyword);

            foreach (Tour tour in searchInTour)
            {
                result.Add(DataConverter.ConvertToTourData(tour));
            }

            TourData tourData;
            foreach (Location location in locations)
            {
                foreach (Schedule schedule in location.Schedules)
                {
                    tourData = DataConverter.ConvertToTourData(schedule.Tour);
                    if (!result.Contains(tourData))
                        result.Add(tourData);
                }
            }
            return result;
        }

        public List<TourData> SearchTourAdvanced(string keyword, int budget, TourType tourTypes, int length)
        {
            List<TourData> result = new List<TourData>();
            List<Tour> tours;

            List<Location> locations = locationProvider.SearchLocation(keyword).ToList();
            tours = tourProvider.SearchTours(keyword).ToList();

            return result;
        }
        #endregion

        #region Get Tours
        public List<TourData> GetLatestTours(double userLatitude, double userLongitude, int numOfResult)
        {
            IQueryable<Tour> tours = tourProvider.GetPublicTours(userLatitude, userLongitude).OrderByDescending(o => o.AddedDate).Take(numOfResult);

            List<TourData> result = new List<TourData>();
            foreach (Tour tour in tours)
                result.Add(DataConverter.ConvertToTourData(tour));
            return result;
        }

        public List<TourData> GetCheapestTours(double userLatitude, double userLongitude, int numOfResult)
        {
            IQueryable<Tour> tours = tourProvider.GetPublicTours(userLatitude, userLongitude).OrderByDescending(o => o.Budget).Take(numOfResult);

            List<TourData> result = new List<TourData>();
            foreach (Tour tour in tours)
                result.Add(DataConverter.ConvertToTourData(tour));
            return result;
        }

        public List<TourData> GetHottestTours(double userLatitude, double userLongitude, int numOfResult)
        {
            IQueryable<Tour> tours = tourProvider.GetPublicTours(userLatitude, userLongitude).OrderByDescending(o => o.Rating).Take(numOfResult);

            List<TourData> result = new List<TourData>();
            foreach (Tour tour in tours)
                result.Add(DataConverter.ConvertToTourData(tour));
            return result;
        }

        public TourData GetLatestTour(double userLatitude, double userLongitude)
        {
            Tour tour = tourProvider.GetPublicTours(userLatitude, userLongitude).OrderByDescending(o => o.AddedDate).FirstOrDefault();
            if (tour == null)
                return null;
            return DataConverter.ConvertToTourData(tour);
        }

        public TourData GetCheapestTour(double userLatitude, double userLongitude)
        {
            Tour tour = tourProvider.GetPublicTours(userLatitude, userLongitude).OrderByDescending(o => o.Budget).FirstOrDefault();
            if (tour == null)
                return null;
            return DataConverter.ConvertToTourData(tour);
        }

        public TourData GetHottestTour(double userLatitude, double userLongitude)
        {
            Tour tour = tourProvider.GetPublicTours(userLatitude, userLongitude).OrderByDescending(o => o.Rating).FirstOrDefault();
            if (tour == null)
                return null;
            return DataConverter.ConvertToTourData(tour);
        }

        public TourData GetTour(int tourId)
        {
            Tour tour = tourProvider.GetTourById(tourId);
            return DataConverter.ConvertToTourData(tour);
        }
        #endregion

        #region Vote Tour
        public bool VoteUpTour(int tourId)
        {
            return tourProvider.VoteUpTour(tourId);
        }

        public bool VoteDownTour(int tourId)
        {
            return tourProvider.VoteDownTour(tourId);
        }
        #endregion
    }
}